package com.brillilab.starter.controller.aio.lab;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.brillilab.common.constant.ResultEnum;
import com.brillilab.common.entity.PageVo;
import com.brillilab.common.entity.ResponseVo;
import com.brillilab.domain.enums.lab.LabMemberPowerEnum;
import com.brillilab.domain.enums.lab.LabUserCardEnum;
import com.brillilab.domain.pa.lab.LabUserCardPa;
import com.brillilab.domain.po.lab.LabDevice;
import com.brillilab.domain.po.lab.LabUserCard;
import com.brillilab.domain.po.user.Users;
import com.brillilab.domain.vo.lab.LabMemberCardVo;
import com.brillilab.domain.vo.lab.LabUserCardVo;
import com.brillilab.domain.vo.user.UserInfoVo;
import com.brillilab.service.core.lab.ILabDeviceService;
import com.brillilab.service.core.lab.ILabUserCardService;
import com.brillilab.service.core.user.IUsersService;
import com.brillilab.service.logic.user.UsersLogic;
import com.brillilab.starter.aspect.AspectLog;
import com.brillilab.starter.constant.StarterConstant;
import com.brillilab.starter.entity.req.lab.BindCardReq;
import com.brillilab.starter.entity.resp.lab.CardStateResp;
import com.brillilab.starter.handler.RequestPower;

/**
 * 实验室用户磁卡API
 *
 * @author lj
 */
@RestController
@RequestMapping("/api/labUserCard")
public class LabUserCardController {
    @Autowired
    private ILabUserCardService labUserCardService;
    @Autowired
    private UsersLogic usersLogic;
    @Autowired
    private IUsersService usersService;
    @Autowired
    private ILabDeviceService labDeviceService;

    /**
     * 分页获取实验室用户磁卡
     *
     * @param cardPa
     * @return
     */
    @PostMapping("/page")
    @RequestPower(LabMemberPowerEnum.user_manage)
    public ResponseVo getPage(@RequestBody LabUserCardPa cardPa,@RequestHeader(name=StarterConstant.TOKEN) String token) {
        Assert.isTrue(cardPa != null && !StringUtils.isBlank(token),"请求参数缺失！");

        UserInfoVo userInfo=usersLogic.getUserByToken(token);

        cardPa.setLabId(userInfo.getLabId());

        PageVo<LabUserCardVo> resultVo=labUserCardService.selectPage(cardPa);

        return ResponseVo.success(resultVo);
    }

    /**
     * 获取状态的Map
     *
     * @param token
     * @return
     */
    @RequestMapping(value="/states", method=RequestMethod.GET)
    @RequestPower(LabMemberPowerEnum.user_manage)
    public ResponseVo getStates(@RequestHeader(name=StarterConstant.TOKEN) String token) {
        List<CardStateResp> states=new ArrayList<>();
        states.add(new CardStateResp(0,"全部"));
        states.add(new CardStateResp(LabUserCardEnum.State.AUTHORIZED));
        states.add(new CardStateResp(LabUserCardEnum.State.TIED_CARD));
        states.add(new CardStateResp(LabUserCardEnum.State.UNBIND));
        return ResponseVo.success(states);
    }


    /**
     * 实验室磁卡授权
     * {\"labId\":\"实验室ID必填L\",\"cardNo\":\"磁卡号必填S\"}
     *
     * @return
     */
    @PostMapping("/empower")
    @RequestPower(LabMemberPowerEnum.user_manage)
    public ResponseVo empowerCard(@RequestHeader(name=StarterConstant.TOKEN) String token,@RequestBody JSONObject json) {

        String cardNo=json.getString("cardNo");

        Assert.isTrue(!StringUtils.isBlank(cardNo) && !StringUtils.isBlank(token),"请求参数缺失！");

        UserInfoVo userInfo=usersLogic.getUserByToken(token);

        LabUserCard card=labUserCardService.selectCard(userInfo.getLabId(),cardNo);
        if(card != null && LabUserCardEnum.State.TIED_CARD.getValue().equals(card.getState())){
            Assert.isTrue(userInfo.getLabId().equals(card.getLabId()),"该磁卡非本实验室磁卡！");
            //如果已绑定，显示绑定者名字
            Users user=usersLogic.getUser(card.getUserId());
            return ResponseVo.failure(ResultEnum.DATA_ALREADY_EXIST,null,user.getName());
        }

        labUserCardService.empowerCard(userInfo.getLabId(),cardNo,userInfo.getName());
        return ResponseVo.success("恭喜，已成功生成授权卡！请取走磁卡！");
    }

    /**
     * 用户磁卡绑定/解绑
     *
     * @param bindPa
     * @return
     */
    @AspectLog
    @PostMapping("/bind")
    @RequestPower(LabMemberPowerEnum.user_manage)
    public ResponseVo bindCard(@RequestBody BindCardReq bindPa,@RequestHeader(name=StarterConstant.TOKEN) String token) {

        Assert.isTrue(!StringUtils.isBlank(token) || !StringUtils.isBlank(bindPa.getCardNo()) && bindPa.getUserId() != null,"请求参数缺失！");

        UserInfoVo userInfo=usersLogic.getUserByToken(token);

        LabUserCard card=labUserCardService.selectCard(userInfo.getLabId(),bindPa.getCardNo());

        if(card != null){
            Assert.isTrue(userInfo.getLabId().equals(card.getLabId()),"该磁卡非本实验室磁卡！");
        }

        if(bindPa.getType() == 1){
            //如果已绑定，显示绑定者名字
            if(card != null){
                if(LabUserCardEnum.State.TIED_CARD.getValue().equals(card.getState())){
                    Users user=usersLogic.getUser(card.getUserId());
                    return ResponseVo.failure(ResultEnum.DATA_ALREADY_EXIST,null,user.getName());
                }
            }
            labUserCardService.bindCard(userInfo.getLabId(),bindPa.getCardNo(),bindPa.getUserId());
            return ResponseVo.success("恭喜，已成功绑定磁卡！");

        } else if(bindPa.getType() == 0){
            labUserCardService.unbindCard(userInfo.getLabId(),bindPa.getCardNo(),bindPa.getUserId());
            return ResponseVo.success("解绑成功！");
        }
        return ResponseVo.failure("操作类型不存在！");
    }

    /**
     * 覆盖绑定
     *
     * @param bindPa cardNo , userId 必填
     * @param token  用户登录Token
     * @return
     * @time 2019-02-18
     */
    @AspectLog
    @PostMapping("/forceBind")
    @RequestPower(LabMemberPowerEnum.user_manage)
    public ResponseVo forceBind(@RequestBody BindCardReq bindPa,@RequestHeader(name=StarterConstant.TOKEN) String token) {
        Assert.isTrue(bindPa != null && StringUtils.isNotBlank(bindPa.getCardNo()) && bindPa.getUserId() != null,"请求参数缺失！");
        UserInfoVo userInfo=usersLogic.getUserByToken(token);
        labUserCardService.forceBindCard(userInfo.getLabId(),bindPa.getCardNo(),bindPa.getUserId());
        return ResponseVo.success(null,"恭喜，已成功绑定磁卡！");
    }

    /**
     * 磁卡重置
     */
    @AspectLog
    @GetMapping("/reset")
    @RequestPower(LabMemberPowerEnum.user_manage)
    public ResponseVo cardReset(String cardNo,@RequestHeader(name=StarterConstant.TOKEN) String token) {
        Assert.isTrue(StringUtils.isNotBlank(cardNo) && StringUtils.isNotBlank(token),"请求参数缺失！");
        UserInfoVo userInfo=usersLogic.getUserByToken(token);
        Assert.isTrue(labUserCardService.resetCard(userInfo.getLabId(),cardNo),"磁卡重置失败！");
        return ResponseVo.success();
    }

    /**
     * 获取实验室成员绑卡关系列表
     *
     * @param deviceNo
     * @return
     */
    @GetMapping("/memberCardList")
    public ResponseVo memberCardList(@RequestParam String deviceNo) {
        LabDevice labDevice=labDeviceService.selectByNo(deviceNo);
        Assert.notNull(labDevice,"一体机编号错误！");
        List<LabMemberCardVo> voList=labUserCardService.memberCardList(labDevice.getLabId());
        return ResponseVo.success(voList);
    }

}
